import { EVENTS, type IEventBus } from '../../events';
import { type RealmBigLevelType } from '../../data/realm';
import {
  CharacterAttributes,
  DEFAULT_INITIAL_BASE_ATTRIBUTES,
  type AttributeModifier,
  type AttributeSource,
} from './character-attributes';
import { BaseModel } from '../base';
import { MODEL_NAME } from '../../constants/model-names';

export class PlayerAttributesModel extends BaseModel {
  public name = MODEL_NAME.PLAYER_ATTRIBUTES;
  private bus: IEventBus;
  private attributes: CharacterAttributes;

  constructor(bus: IEventBus) {
    super();
    this.bus = bus;
    this.attributes = new CharacterAttributes(DEFAULT_INITIAL_BASE_ATTRIBUTES);
  }

  public calculateFinalAttributes() {
    return this.attributes.calculateFinalAttributes();
  }

  public setLevel(level: number): void {
    this.attributes.setLevel(level);
    this.bus.emit(EVENTS.PLAYER_ATTRIBUTES_STATE_UPDATE);
  }

  public setRealm(bigLevelType: RealmBigLevelType, smallLevel?: number) {
    this.attributes.setRealm(bigLevelType, smallLevel);
    this.bus.emit(EVENTS.PLAYER_ATTRIBUTES_STATE_UPDATE);
  }

  public addModifier(modifier: AttributeModifier) {
    this.attributes.addModifier(modifier);
    this.bus.emit(EVENTS.PLAYER_ATTRIBUTES_STATE_UPDATE);
  }

  public removeModifier(source: AttributeSource, key: string) {
    this.attributes.removeModifier(source, key);
    this.bus.emit(EVENTS.PLAYER_ATTRIBUTES_STATE_UPDATE);
  }

  public removeModifiersBySource(source: AttributeSource) {
    this.attributes.removeModifiersBySource(source);
    this.bus.emit(EVENTS.PLAYER_ATTRIBUTES_STATE_UPDATE);
  }

  public getModifiers() {
    return this.attributes.getModifiers();
  }

  public get uiState() {
    return this.attributes.getAttributeSnapshot();
  }
}
